package com.ls.mysql.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ls.mysql.dao.SurplusDao;
import com.ls.mysql.dao.UserDao;
import com.ls.mysql.entity.YzUsers;
import com.ls.mysql.other.Thread1;
import com.ls.mysql.service.UserService;
import com.ls.mysql.util.EncryptUtil;
import com.ls.mysql.util.Page;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao ud;
    @Autowired
    private SurplusDao spd;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Override
    public YzUsers UserLogin(String account, String password) {
        return this.ud.UserLogin(account, password);
    }

    @Override
    public int UserRegister(YzUsers user) {
        this.ud.UserRegister(user);
        return this.spd.InitSurplus(user.getId(), "1.00");
    }

    @Override
    public int isExistUser(String UUID) {
        return this.ud.isExistUser(UUID);
    }

    @Override
    public int isExistUsername(String username) {
        return this.ud.isExistUsername(username);
    }

    @Override
    public int updateUser(YzUsers user) {
        return this.ud.updateUser(user);
    }

    @Override
    public int deleteUser(String user_id) {
        return this.ud.deleteUser(user_id);
    }

    @Override
    public Page<YzUsers> queryAllUsers(Integer pageNum, Integer pageSize) {
        Page<YzUsers> p = null;
        int totalcount = queryTotalUser();
        if (totalcount > 0) {
            p = new Page<YzUsers>(pageNum, pageSize, totalcount);
            List<YzUsers> list = this.ud.queryAllUsers(p.getIndex(), p.getPageSize());
            p.setList(list);
            return p;
        }
        return null;
    }

    @Override
    public int queryTotalUser() {
        return this.ud.queryTotalUser();
    }

    @Override
    public int BatchInsertUsers(List<Map<String, String>> list, Integer status) {
        Map<String, Object> mvp = new LinkedHashMap<>();
        //设置该批成员的身份类型
        mvp.put("status", status);
        //将List<Map>转化为List<YzUsers>
        List<YzUsers> userlist = new ArrayList<>();
        //存储每个用户的id,当user存在时为其添加账户关联
        List<String> ids = new ArrayList<>();
        YzUsers u = null;
        for (Map<String, String> ul : list) {
            u = new YzUsers();
            //填充用户id
            String create_uid = "";
            while (true) {
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                int count = isExistUser(uuid);
                if (count == 0) {
                    create_uid = uuid;
                    break;
                }
            }
            u.setId(create_uid);
            ids.add(create_uid);
            //填充其余属性
            Iterator<Map.Entry<String, String>> it = ul.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, String> map = it.next();
                if (map.getKey().equals("realname")) u.setRealname(map.getValue());
                if (map.getKey().equals("username")) u.setUsername(map.getValue());
                if (map.getKey().equals("password")) u.setPassword(map.getValue());
                if (map.getKey().equals("qq")) u.setQq(map.getValue());
                if (map.getKey().equals("email")) u.setEmail(map.getValue());
                if (map.getKey().equals("wechat")) u.setWechat(map.getValue());
                if (map.getKey().equals("mobile")) u.setMobile(map.getValue());
                if (map.getKey().equals("address")) u.setAddress(map.getValue());
                if (map.getKey().equals("age")) {
                    String ageSTR = map.getValue();
                    if (ageSTR != null || !ageSTR.equals("")) u.setAge(Integer.parseInt(ageSTR));
                }
                if (map.getKey().equals("sex")) u.setSex(map.getValue());
                if (map.getKey().equals("derive")) u.setDerive(map.getValue());
                if (map.getKey().equals("hobby")) u.setHobby(map.getValue());
                //System.out.println(map.getKey()+"******"+map.getValue());
            }
            userlist.add(u);
        }
        mvp.put("userlist", userlist);
        //批量插入，返回影响行数
        int AffectLine = this.ud.BatchInsertUsers(mvp);
        //为每个用户初始化账户
        for (String id : ids)
            this.spd.InitSurplus(id, "1.00");
        return AffectLine;
    }

    @Override
    public List<YzUsers> BatchFind(List<String> user_ids) {
        return this.ud.BatchFind(user_ids);
    }

    @Override
    public JSONObject ThreadTest(HttpServletRequest request) {
        JSONObject json = new JSONObject();
        String msg = "操作码有误";
        int statusCode = -1;
        String type = (request.getParameter("exec_type") == null || request.getParameter("exec_type") == "") ? null : request.getParameter("exec_type");
        if (type != null) {
            if ("1".equals(type)) {
                int affectLine = ud.deleteFrom();
                msg = "操作已执行，已删除" + affectLine + "条数据";
                statusCode = 1;
            } else if ("2".equals(type)) {
                try {
                    String shuliang = (request.getParameter("count") == null || request.getParameter("count") == "") ? null : request.getParameter("count");
                    if (shuliang != null) {
                        int shuLiang = Integer.parseInt(shuliang);
                        // 生成一定数量的用户
                        List<YzUsers> list = new ArrayList<>();
                        YzUsers yu;
                        for (int i = 0; i < 10000; i++) {
                            yu = new YzUsers();
                            yu.setId("u" + Integer.toString(i + 1));
                            yu.setRealname("张" + Integer.toString(i));
                            yu.setUsername("zhangsan" + Integer.toString(i));
                            // 使用MD5一次加密后的串存入数据库
                            yu.setPassword(EncryptUtil.getMD5String("123456"));
                            // 允许为空的部分
                            yu.setQq("qq_" + Integer.toString(i + 1));
                            yu.setEmail("email_" + Integer.toString(i + 1));
                            yu.setWechat("WeChat_" + Integer.toString(i + 1));
                            yu.setMobile("mobile_" + Integer.toString(i + 1));
                            yu.setAddress("address_" + Integer.toString(i + 1));
                            // 年龄 随机数[16,35)
                            yu.setAge((int) Math.random() * (35 - 16) + 16);
                            yu.setSex("男");
                            yu.setDerive("Earth");
                            yu.setHobby("this.爱好");
                            yu.setU_img("https://www.baidu.com/");
                            list.add(yu);
                        }
                        /**
                         * 每个线程插入的数据为1000 <--- 最优效率
                         * 根据数据记录数获得线程总数，但是并发只有10个线程
                         * 根据线程总数对数据进行切割
                         */
                        int mod_ = 1000;
                        int Thread_size = (list.size() % mod_ == 0) ? (list.size() / mod_) : ((list.size() / mod_) + 1);
                        List<List<YzUsers>> lis = new ArrayList<>(Thread_size);
                        for (int i = 0; i < Thread_size; i++) { //[a,b) [0,1000)
                            if (i == (Thread_size - 1)) {
                                if (list.size() % mod_ > 0) {
                                    lis.add(list.subList(i * mod_, i * mod_ + list.size() % 1000));
                                } else {
                                    lis.add(list.subList(i * mod_, i * mod_ + mod_));
                                }
                            } else {
                                lis.add(list.subList(i * mod_, i * mod_ + mod_));
                            }
                        }
                        long startTime = System.currentTimeMillis();
                        Thread[] ts = new Thread[Thread_size];
                        for (int i = 0; i < Thread_size; i++) {
                            ts[i] = new Thread(new Thread1(lis.get(i), ud, spd, sqlSessionFactory));
                            ts[i].start();
                            ts[i].join();
                        }
                        long endTime = System.currentTimeMillis();
                        String useTime = String.valueOf(endTime - startTime) + "ms";
                        json.put("log", "生成" + shuliang + "条数据所耗费的时间为：" + useTime);
                        msg = "操作已执行，已生成" + shuLiang + "条数据";
                        statusCode = 1;
                    }
                } catch (Exception e) {
                    msg = "生成数据数错误，应为数字";
                }
            }
        }
        json.put("statusCode", statusCode);
        json.put("msg", msg);
        return json;
    }

    @Override
    public List<YzUsers> findAllUsers() {
        return this.ud.findAllUsers();
    }
}
